/**
 * 端到端集成测试套件
 * End-to-End Integration Test Suite
 */

const http = require('http');
const https = require('https');
const fs = require('fs').promises;
const path = require('path');
const mysql = require('mysql2/promise');
const FormData = require('form-data');
const { exec } = require('child_process');
const { promisify } = require('util');

const execAsync = promisify(exec);

// 加载配置
require('dotenv').config({ path: path.join(__dirname, '../../.env') });

const config = {
  app: {
    baseUrl: process.env.BASE_URL || 'http://localhost:3000',
    timeout: 30000
  },
  database: {
    host: process.env.DB_HOST || 'localhost',
    port: process.env.DB_PORT || 3306,
    user: process.env.DB_USER || 'notes_user',
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME || 'personal_cloud_notes'
  },
  test: {
    adminEmail: 'admin@test.com',
    adminPassword: 'TestAdmin123!',
    testUserEmail: 'testuser@test.com',
    testUserPassword: 'TestUser123!',
    testUserNickname: '测试用户'
  }
};

// 测试结果统计
let totalTests = 0;
let passedTests = 0;
let failedTests = 0;
const testResults = [];

// 颜色定义
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  purple: '\x1b[35m',
  cyan: '\x1b[36m'
};

/**
 * 打印带颜色的消息
 */
function printMessage(color, message) {
  console.log(`${color}${message}${colors.reset}`);
}

/**
 * HTTP请求工具函数
 */
function makeRequest(options, data = null) {
  return new Promise((resolve, reject) => {
    const protocol = options.protocol === 'https:' ? https : http;
    
    const req = protocol.request(options, (res) => {
      let responseData = '';
      
      res.on('data', (chunk) => {
        responseData += chunk;
      });
      
      res.on('end', () => {
        try {
          const parsedData = responseData ? JSON.parse(responseData) : {};
          resolve({
            statusCode: res.statusCode,
            headers: res.headers,
            data: parsedData,
            rawData: responseData
          });
        } catch (error) {
          resolve({
            statusCode: res.statusCode,
            headers: res.headers,
            data: null,
            rawData: responseData
          });
        }
      });
    });
    
    req.on('error', (error) => {
      reject(error);
    });
    
    req.setTimeout(config.app.timeout, () => {
      req.destroy();
      reject(new Error('请求超时'));
    });
    
    if (data) {
      if (data instanceof FormData) {
        data.pipe(req);
      } else {
        req.write(typeof data === 'string' ? data : JSON.stringify(data));
        req.end();
      }
    } else {
      req.end();
    }
  });
}

/**
 * 解析URL
 */
function parseUrl(url) {
  const urlObj = new URL(url);
  return {
    protocol: urlObj.protocol,
    hostname: urlObj.hostname,
    port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
    path: urlObj.pathname + urlObj.search
  };
}

/**
 * 运行测试
 */
async function runTest(testName, testFunction) {
  totalTests++;
  process.stdout.write(`运行测试: ${testName} ... `);
  
  try {
    const startTime = Date.now();
    await testFunction();
    const duration = Date.now() - startTime;
    
    printMessage(colors.green, `✓ 通过 (${duration}ms)`);
    passedTests++;
    testResults.push({ name: testName, status: 'PASS', duration });
  } catch (error) {
    printMessage(colors.red, `✗ 失败`);
    printMessage(colors.red, `  错误: ${error.message}`);
    failedTests++;
    testResults.push({ name: testName, status: 'FAIL', error: error.message });
  }
}

/**
 * 测试套件：用户认证流程
 */
class AuthenticationTestSuite {
  constructor() {
    this.authToken = null;
    this.adminToken = null;
  }

  /**
   * 测试管理员登录
   */
  async testAdminLogin() {
    const url = parseUrl(`${config.app.baseUrl}/api/auth/login`);
    const loginData = {
      email: config.test.adminEmail,
      password: config.test.adminPassword
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }, loginData);

    if (response.statusCode !== 200) {
      throw new Error(`管理员登录失败: ${response.statusCode} - ${response.rawData}`);
    }

    if (!response.data.success || !response.data.token) {
      throw new Error('管理员登录响应格式错误');
    }

    this.adminToken = response.data.token;
  }

  /**
   * 测试创建测试用户
   */
  async testCreateTestUser() {
    if (!this.adminToken) {
      throw new Error('需要管理员权限');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/admin/users`);
    const userData = {
      email: config.test.testUserEmail,
      password: config.test.testUserPassword,
      nickname: config.test.testUserNickname
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.adminToken}`
      }
    }, userData);

    // 如果用户已存在，不算错误
    if (response.statusCode === 409) {
      return;
    }

    if (response.statusCode !== 200) {
      throw new Error(`创建测试用户失败: ${response.statusCode} - ${response.rawData}`);
    }

    if (!response.data.success) {
      throw new Error('创建测试用户响应格式错误');
    }
  }

  /**
   * 测试用户登录
   */
  async testUserLogin() {
    const url = parseUrl(`${config.app.baseUrl}/api/auth/login`);
    const loginData = {
      email: config.test.testUserEmail,
      password: config.test.testUserPassword
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }, loginData);

    if (response.statusCode !== 200) {
      throw new Error(`用户登录失败: ${response.statusCode} - ${response.rawData}`);
    }

    if (!response.data.success || !response.data.token) {
      throw new Error('用户登录响应格式错误');
    }

    this.authToken = response.data.token;
  }

  /**
   * 测试token验证
   */
  async testTokenVerification() {
    if (!this.authToken) {
      throw new Error('需要用户token');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/auth/verify`);
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`Token验证失败: ${response.statusCode}`);
    }

    if (!response.data.success || !response.data.user) {
      throw new Error('Token验证响应格式错误');
    }
  }

  /**
   * 测试用户登出
   */
  async testUserLogout() {
    if (!this.authToken) {
      throw new Error('需要用户token');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/auth/logout`);
    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`用户登出失败: ${response.statusCode}`);
    }

    if (!response.data.success) {
      throw new Error('用户登出响应格式错误');
    }
  }

  /**
   * 测试无效凭据登录
   */
  async testInvalidCredentials() {
    const url = parseUrl(`${config.app.baseUrl}/api/auth/login`);
    const loginData = {
      email: 'invalid@test.com',
      password: 'wrongpassword'
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      }
    }, loginData);

    if (response.statusCode === 200) {
      throw new Error('无效凭据登录应该失败');
    }

    if (response.statusCode !== 401 && response.statusCode !== 400) {
      throw new Error(`无效凭据登录返回了意外的状态码: ${response.statusCode}`);
    }
  }
}

/**
 * 测试套件：笔记管理流程
 */
class NotesTestSuite {
  constructor(authToken) {
    this.authToken = authToken;
    this.testNoteId = null;
  }

  /**
   * 测试创建笔记
   */
  async testCreateNote() {
    const url = parseUrl(`${config.app.baseUrl}/api/notes`);
    const noteData = {
      title: '测试笔记标题',
      content: '<p>这是一个测试笔记的内容，包含<strong>粗体</strong>和<em>斜体</em>文本。</p>'
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      }
    }, noteData);

    if (response.statusCode !== 200) {
      throw new Error(`创建笔记失败: ${response.statusCode} - ${response.rawData}`);
    }

    if (!response.data.success || !response.data.note || !response.data.note.id) {
      throw new Error('创建笔记响应格式错误');
    }

    this.testNoteId = response.data.note.id;
  }

  /**
   * 测试获取笔记列表
   */
  async testGetNotesList() {
    const url = parseUrl(`${config.app.baseUrl}/api/notes?page=1&limit=10`);
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`获取笔记列表失败: ${response.statusCode}`);
    }

    if (!response.data.notes || !Array.isArray(response.data.notes)) {
      throw new Error('获取笔记列表响应格式错误');
    }

    // 验证刚创建的笔记是否在列表中
    const createdNote = response.data.notes.find(note => note.id === this.testNoteId);
    if (!createdNote) {
      throw new Error('创建的笔记未出现在列表中');
    }
  }

  /**
   * 测试获取单个笔记
   */
  async testGetSingleNote() {
    if (!this.testNoteId) {
      throw new Error('需要先创建笔记');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/notes/${this.testNoteId}`);
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`获取单个笔记失败: ${response.statusCode}`);
    }

    if (!response.data.note || response.data.note.id !== this.testNoteId) {
      throw new Error('获取单个笔记响应格式错误');
    }
  }

  /**
   * 测试更新笔记
   */
  async testUpdateNote() {
    if (!this.testNoteId) {
      throw new Error('需要先创建笔记');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/notes/${this.testNoteId}`);
    const updateData = {
      title: '更新后的测试笔记标题',
      content: '<p>这是更新后的笔记内容，包含<strong>新的内容</strong>。</p>'
    };

    const response = await makeRequest({
      ...url,
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      }
    }, updateData);

    if (response.statusCode !== 200) {
      throw new Error(`更新笔记失败: ${response.statusCode}`);
    }

    if (!response.data.success || !response.data.note) {
      throw new Error('更新笔记响应格式错误');
    }

    // 验证更新是否生效
    if (response.data.note.title !== updateData.title) {
      throw new Error('笔记标题更新失败');
    }
  }

  /**
   * 测试搜索笔记
   */
  async testSearchNotes() {
    const url = parseUrl(`${config.app.baseUrl}/api/notes/search?q=测试`);
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`搜索笔记失败: ${response.statusCode}`);
    }

    if (!response.data.notes || !Array.isArray(response.data.notes)) {
      throw new Error('搜索笔记响应格式错误');
    }

    // 验证搜索结果包含我们的测试笔记
    const foundNote = response.data.notes.find(note => note.id === this.testNoteId);
    if (!foundNote) {
      throw new Error('搜索结果中未找到测试笔记');
    }
  }

  /**
   * 测试删除笔记
   */
  async testDeleteNote() {
    if (!this.testNoteId) {
      throw new Error('需要先创建笔记');
    }

    const url = parseUrl(`${config.app.baseUrl}/api/notes/${this.testNoteId}`);
    const response = await makeRequest({
      ...url,
      method: 'DELETE',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`删除笔记失败: ${response.statusCode}`);
    }

    if (!response.data.success) {
      throw new Error('删除笔记响应格式错误');
    }

    // 验证笔记已被删除
    const getUrl = parseUrl(`${config.app.baseUrl}/api/notes/${this.testNoteId}`);
    const getResponse = await makeRequest({
      ...getUrl,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (getResponse.statusCode !== 404) {
      throw new Error('删除的笔记仍然可以访问');
    }
  }
}

/**
 * 测试套件：文件管理流程
 */
class FileManagementTestSuite {
  constructor(authToken) {
    this.authToken = authToken;
    this.uploadedFiles = [];
  }

  /**
   * 创建测试文件
   */
  async createTestFile(filename, content) {
    const testFilePath = path.join(__dirname, 'temp', filename);
    await fs.mkdir(path.dirname(testFilePath), { recursive: true });
    await fs.writeFile(testFilePath, content);
    return testFilePath;
  }

  /**
   * 测试文件上传
   */
  async testFileUpload() {
    // 创建测试文件
    const testContent = 'This is a test file content for integration testing.';
    const testFilePath = await this.createTestFile('test-upload.txt', testContent);

    const url = parseUrl(`${config.app.baseUrl}/api/files/upload`);
    const form = new FormData();
    form.append('files', await fs.readFile(testFilePath), {
      filename: 'test-upload.txt',
      contentType: 'text/plain'
    });

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.authToken}`,
        ...form.getHeaders()
      }
    }, form);

    if (response.statusCode !== 200) {
      throw new Error(`文件上传失败: ${response.statusCode} - ${response.rawData}`);
    }

    if (!response.data.success || !response.data.files || response.data.files.length === 0) {
      throw new Error('文件上传响应格式错误');
    }

    this.uploadedFiles.push(response.data.files[0]);

    // 清理测试文件
    await fs.unlink(testFilePath);
  }

  /**
   * 测试获取文件列表
   */
  async testGetFilesList() {
    const url = parseUrl(`${config.app.baseUrl}/api/files?path=/`);
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`获取文件列表失败: ${response.statusCode}`);
    }

    if (!response.data.files || !Array.isArray(response.data.files)) {
      throw new Error('获取文件列表响应格式错误');
    }

    // 验证上传的文件是否在列表中
    if (this.uploadedFiles.length > 0) {
      const uploadedFile = this.uploadedFiles[0];
      const foundFile = response.data.files.find(file => file.filename === uploadedFile.filename);
      if (!foundFile) {
        throw new Error('上传的文件未出现在文件列表中');
      }
    }
  }

  /**
   * 测试创建文件夹
   */
  async testCreateFolder() {
    const url = parseUrl(`${config.app.baseUrl}/api/files/folder`);
    const folderData = {
      path: '/',
      name: 'test-folder'
    };

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      }
    }, folderData);

    if (response.statusCode !== 200) {
      throw new Error(`创建文件夹失败: ${response.statusCode}`);
    }

    if (!response.data.success) {
      throw new Error('创建文件夹响应格式错误');
    }
  }

  /**
   * 测试文件下载
   */
  async testFileDownload() {
    if (this.uploadedFiles.length === 0) {
      throw new Error('需要先上传文件');
    }

    const uploadedFile = this.uploadedFiles[0];
    const url = parseUrl(`${config.app.baseUrl}/api/files/download?path=${encodeURIComponent(uploadedFile.file_path)}`);
    
    const response = await makeRequest({
      ...url,
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${this.authToken}`
      }
    });

    if (response.statusCode !== 200) {
      throw new Error(`文件下载失败: ${response.statusCode}`);
    }

    // 验证下载的内容
    if (!response.rawData || response.rawData.length === 0) {
      throw new Error('下载的文件内容为空');
    }
  }

  /**
   * 测试删除文件
   */
  async testDeleteFile() {
    if (this.uploadedFiles.length === 0) {
      throw new Error('需要先上传文件');
    }

    const uploadedFile = this.uploadedFiles[0];
    const url = parseUrl(`${config.app.baseUrl}/api/files`);
    const deleteData = {
      path: uploadedFile.file_path
    };

    const response = await makeRequest({
      ...url,
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      }
    }, deleteData);

    if (response.statusCode !== 200) {
      throw new Error(`删除文件失败: ${response.statusCode}`);
    }

    if (!response.data.success) {
      throw new Error('删除文件响应格式错误');
    }
  }

  /**
   * 测试大文件上传
   */
  async testLargeFileUpload() {
    // 创建一个较大的测试文件 (1MB)
    const largeContent = 'A'.repeat(1024 * 1024);
    const testFilePath = await this.createTestFile('large-test-file.txt', largeContent);

    const url = parseUrl(`${config.app.baseUrl}/api/files/upload`);
    const form = new FormData();
    form.append('files', await fs.readFile(testFilePath), {
      filename: 'large-test-file.txt',
      contentType: 'text/plain'
    });

    const response = await makeRequest({
      ...url,
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.authToken}`,
        ...form.getHeaders()
      }
    }, form);

    if (response.statusCode !== 200) {
      throw new Error(`大文件上传失败: ${response.statusCode}`);
    }

    if (!response.data.success || !response.data.files || response.data.files.length === 0) {
      throw new Error('大文件上传响应格式错误');
    }

    // 清理测试文件
    await fs.unlink(testFilePath);
    
    // 删除上传的大文件
    const uploadedFile = response.data.files[0];
    const deleteUrl = parseUrl(`${config.app.baseUrl}/api/files`);
    await makeRequest({
      ...deleteUrl,
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${this.authToken}`
      }
    }, { path: uploadedFile.file_path });
  }
}

/**
 * 测试套件：系统性能测试
 */
class PerformanceTestSuite {
  constructor(authToken) {
    this.authToken = authToken;
  }

  /**
   * 测试并发登录
   */
  async testConcurrentLogins() {
    const concurrentRequests = 10;
    const promises = [];

    for (let i = 0; i < concurrentRequests; i++) {
      const url = parseUrl(`${config.app.baseUrl}/api/auth/login`);
      const loginData = {
        email: config.test.testUserEmail,
        password: config.test.testUserPassword
      };

      const promise = makeRequest({
        ...url,
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      }, loginData);

      promises.push(promise);
    }

    const results = await Promise.allSettled(promises);
    const successCount = results.filter(result => 
      result.status === 'fulfilled' && result.value.statusCode === 200
    ).length;

    if (successCount < concurrentRequests * 0.8) {
      throw new Error(`并发登录成功率过低: ${successCount}/${concurrentRequests}`);
    }
  }

  /**
   * 测试API响应时间
   */
  async testApiResponseTime() {
    const endpoints = [
      { path: '/api/auth/verify', method: 'GET' },
      { path: '/api/notes', method: 'GET' },
      { path: '/api/files?path=/', method: 'GET' }
    ];

    for (const endpoint of endpoints) {
      const startTime = Date.now();
      const url = parseUrl(`${config.app.baseUrl}${endpoint.path}`);
      
      const response = await makeRequest({
        ...url,
        method: endpoint.method,
        headers: {
          'Authorization': `Bearer ${this.authToken}`
        }
      });

      const responseTime = Date.now() - startTime;

      if (response.statusCode !== 200) {
        throw new Error(`API ${endpoint.path} 响应失败: ${response.statusCode}`);
      }

      if (responseTime > 5000) {
        throw new Error(`API ${endpoint.path} 响应时间过长: ${responseTime}ms`);
      }
    }
  }

  /**
   * 测试内存使用情况
   */
  async testMemoryUsage() {
    try {
      const { stdout } = await execAsync('free -m | awk \'NR==2{printf "%s %s", $3*100/$2, $3}\'');
      const [usagePercent, usedMB] = stdout.trim().split(' ').map(Number);

      if (usagePercent > 90) {
        throw new Error(`内存使用率过高: ${usagePercent}% (${usedMB}MB)`);
      }
    } catch (error) {
      if (error.message.includes('内存使用率过高')) {
        throw error;
      }
      // 如果无法获取内存信息，跳过此测试
      console.warn('无法获取内存使用信息，跳过内存测试');
    }
  }

  /**
   * 测试数据库连接池
   */
  async testDatabaseConnectionPool() {
    const connections = [];
    const maxConnections = 5;

    try {
      // 创建多个数据库连接
      for (let i = 0; i < maxConnections; i++) {
        const connection = await mysql.createConnection({
          host: config.database.host,
          port: config.database.port,
          user: config.database.user,
          password: config.database.password,
          database: config.database.database
        });
        connections.push(connection);
      }

      // 测试所有连接是否正常工作
      const promises = connections.map(conn => conn.execute('SELECT 1'));
      await Promise.all(promises);

    } finally {
      // 关闭所有连接
      for (const connection of connections) {
        await connection.end();
      }
    }
  }
}

/**
 * 清理测试数据
 */
async function cleanupTestData() {
  let connection;
  try {
    connection = await mysql.createConnection({
      host: config.database.host,
      port: config.database.port,
      user: config.database.user,
      password: config.database.password,
      database: config.database.database
    });

    // 删除测试用户及其相关数据
    await connection.execute('DELETE FROM files WHERE user_id IN (SELECT id FROM users WHERE email = ?)', [config.test.testUserEmail]);
    await connection.execute('DELETE FROM notes WHERE user_id IN (SELECT id FROM users WHERE email = ?)', [config.test.testUserEmail]);
    await connection.execute('DELETE FROM users WHERE email = ?', [config.test.testUserEmail]);

    // 清理临时文件
    const tempDir = path.join(__dirname, 'temp');
    try {
      await fs.rmdir(tempDir, { recursive: true });
    } catch (error) {
      // 忽略清理错误
    }

  } catch (error) {
    console.warn('清理测试数据时发生错误:', error.message);
  } finally {
    if (connection) {
      await connection.end();
    }
  }
}

/**
 * 生成测试报告
 */
function generateTestReport() {
  const reportPath = path.join(__dirname, `../reports/e2e-test-report-${Date.now()}.json`);
  
  const report = {
    timestamp: new Date().toISOString(),
    summary: {
      total: totalTests,
      passed: passedTests,
      failed: failedTests,
      success_rate: Math.round((passedTests / totalTests) * 100)
    },
    results: testResults,
    config: {
      base_url: config.app.baseUrl,
      timeout: config.app.timeout
    }
  };

  require('fs').writeFileSync(reportPath, JSON.stringify(report, null, 2));
  printMessage(colors.blue, `测试报告已生成: ${reportPath}`);
}

/**
 * 主测试函数
 */
async function runE2ETests() {
  printMessage(colors.cyan, '个人云笔记端到端集成测试');
  printMessage(colors.cyan, '================================');
  console.log();

  try {
    // 初始化测试套件
    const authSuite = new AuthenticationTestSuite();
    
    // 用户认证流程测试
    printMessage(colors.yellow, '1. 用户认证流程测试');
    await runTest('管理员登录', () => authSuite.testAdminLogin());
    await runTest('创建测试用户', () => authSuite.testCreateTestUser());
    await runTest('用户登录', () => authSuite.testUserLogin());
    await runTest('Token验证', () => authSuite.testTokenVerification());
    await runTest('无效凭据登录', () => authSuite.testInvalidCredentials());
    
    console.log();
    
    // 笔记管理流程测试
    printMessage(colors.yellow, '2. 笔记管理流程测试');
    const notesSuite = new NotesTestSuite(authSuite.authToken);
    await runTest('创建笔记', () => notesSuite.testCreateNote());
    await runTest('获取笔记列表', () => notesSuite.testGetNotesList());
    await runTest('获取单个笔记', () => notesSuite.testGetSingleNote());
    await runTest('更新笔记', () => notesSuite.testUpdateNote());
    await runTest('搜索笔记', () => notesSuite.testSearchNotes());
    await runTest('删除笔记', () => notesSuite.testDeleteNote());
    
    console.log();
    
    // 文件管理流程测试
    printMessage(colors.yellow, '3. 文件管理流程测试');
    const filesSuite = new FileManagementTestSuite(authSuite.authToken);
    await runTest('文件上传', () => filesSuite.testFileUpload());
    await runTest('获取文件列表', () => filesSuite.testGetFilesList());
    await runTest('创建文件夹', () => filesSuite.testCreateFolder());
    await runTest('文件下载', () => filesSuite.testFileDownload());
    await runTest('大文件上传', () => filesSuite.testLargeFileUpload());
    await runTest('删除文件', () => filesSuite.testDeleteFile());
    
    console.log();
    
    // 系统性能测试
    printMessage(colors.yellow, '4. 系统性能测试');
    const perfSuite = new PerformanceTestSuite(authSuite.authToken);
    await runTest('并发登录测试', () => perfSuite.testConcurrentLogins());
    await runTest('API响应时间测试', () => perfSuite.testApiResponseTime());
    await runTest('内存使用测试', () => perfSuite.testMemoryUsage());
    await runTest('数据库连接池测试', () => perfSuite.testDatabaseConnectionPool());
    
    console.log();
    
    // 用户登出测试
    await runTest('用户登出', () => authSuite.testUserLogout());

  } catch (error) {
    printMessage(colors.red, `测试执行过程中发生严重错误: ${error.message}`);
  } finally {
    // 清理测试数据
    await cleanupTestData();
  }

  // 显示测试总结
  console.log();
  printMessage(colors.blue, '测试总结:');
  printMessage(colors.green, `✓ 通过: ${passedTests}`);
  printMessage(colors.red, `✗ 失败: ${failedTests}`);
  printMessage(colors.blue, `总计: ${totalTests}`);

  const successRate = Math.round((passedTests / totalTests) * 100);
  console.log();

  if (failedTests === 0) {
    printMessage(colors.green, '🎉 所有端到端测试都通过！');
  } else if (successRate >= 80) {
    printMessage(colors.yellow, `⚠️  部分测试失败 (成功率: ${successRate}%)，但主要功能正常。`);
  } else {
    printMessage(colors.red, `❌ 多个测试失败 (成功率: ${successRate}%)，系统可能存在问题。`);
  }

  // 生成测试报告
  generateTestReport();

  // 返回适当的退出码
  process.exit(failedTests > 0 ? 1 : 0);
}

// 错误处理
process.on('unhandledRejection', (error) => {
  printMessage(colors.red, `未处理的错误: ${error.message}`);
  process.exit(1);
});

// 运行主函数
if (require.main === module) {
  runE2ETests().catch((error) => {
    printMessage(colors.red, `测试启动失败: ${error.message}`);
    process.exit(1);
  });
}

module.exports = {
  AuthenticationTestSuite,
  NotesTestSuite,
  FileManagementTestSuite,
  PerformanceTestSuite,
  runE2ETests
};